package inferenceEngine.labels;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.XMLWriter;

import common.Pair;

/**
 * A collection of labels, support changing recommended degree
 * @author Boshi Li
 *
 */
public class LabelManager {
	
	HashMap<String, Label> labels = new HashMap<String, Label>();
	private String path = "data/rules.xml";
	private double changeStep = 0.01;
	
	public LabelManager(){
		init();
		
		
	}
	
	public void adjustChange( ArrayList<Pair<Label,Boolean>> labels ){
		init();
		 Document doc;
			try {
				String info = readFile(path);
				doc = DocumentHelper.parseText( info );
				 Element rootElt = doc.getRootElement();
				 List<Element> elements = rootElt.elements("label");
				 HashMap< String, Element> map = new HashMap< String, Element>();
				 for( Element e : elements ){
					 map.put( e.attributeValue("name"),  e );
				 }
				for( Pair<Label,Boolean> pair : labels ){
					String name = pair.first.getValue();
					Element e = map.get(name);
					double change = 0;
					if( pair.second == true ){
						change = changeStep;
					}else{
						change = -changeStep;
					}
					pair.first.setDegree( pair.first.getDegree() + change );
					e.attribute("degree").setValue( String.valueOf( pair.first.getDegree() + change) );
				}
				XMLWriter output = new XMLWriter(new FileWriter(new File(  path)));  
	            output.write( doc );  
	            output.close();  
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	
	}
	
	private void add( Element e ){
		String name = e.attributeValue("name");
		double degree = Double.parseDouble( e.attributeValue("degree") );
		labels.put(name, new Label(name, degree));
	}
	
	public Label generate(String name){
		if( labels.containsKey(name) ){
			return labels.get(name);
		}else{
			return new Label(name);
		}		
	}

	 private String readFile( String path ) throws Exception{
	    	BufferedReader br = new BufferedReader(new FileReader(path));
	    	StringBuilder sb = new StringBuilder();
	        try {            
	            String line = br.readLine();

	            while (line != null) {
	                sb.append(line);
	                sb.append(System.lineSeparator());
	                line = br.readLine();
	            }
	           
	        } finally {
	            br.close();
	        }
	        return sb.toString();
	    }
	 
	 private void init(){
		 labels.clear();
		 Document doc;
			try {
				String info = readFile(path);
				doc = DocumentHelper.parseText( info );
				 Element rootElt = doc.getRootElement();
				 List<Element> elements = rootElt.elements();
				 for( Element element: elements ){
					 if( element.getName().equals("label") ){
						add(element);
					 }
				 }
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	 }
}
